package com.service.admin.admin.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Maps;
import com.service.admin.admin.controller.request.*;
import com.service.admin.admin.controller.response.SysUserResp;
import com.service.admin.admin.controller.response.UserInfoRep;
import com.service.admin.admin.dto.LoginUserSession;
import com.service.admin.admin.enums.AdminUserEnums;
import com.service.admin.admin.model.SysUserPage;
import com.service.admin.admin.service.SysUserService;
import com.service.admin.utils.TotpUtils;
import com.service.core.exception.CommonException;
import com.service.core.rest.response.CommonPageRep;
import com.service.dao.query.SysUserPrams;
import com.service.dao.mapper.SysRoleMapper;
import com.service.dao.mapper.SysUserMapper;
import com.service.dao.mapper.SysUserRoleMapper;
import com.service.dao.model.SysUser;
import com.service.admin.support.SessionUtil;
import com.service.utility.modelmapper.ModelMapperUtil;
import com.service.admin.utils.PwdUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <dl>
 * <dt>back-end</dt>
 * <dd>Description:</dd>
 * <dd>Copyright: Copyright (C) 2015</dd>
 * <dd>Company: </dd>
 * <dd>CreateDate: 2019年08月01日</dd>
 * </dl>
 *
 * @author
 */
@Service
@Transactional(readOnly = true, rollbackFor = Exception.class)
public class SysUserServiceImpl implements SysUserService {

    @Autowired
    private SessionUtil sessionUtil;
    @Autowired
    private SysRoleMapper roleMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserInfoRep doLogin(LoginReq loginReq) {
        Map<String, Object> param = new HashMap<>();
        param.put("login_name", loginReq.getLoginName());
        param.put("user_status", AdminUserEnums.Status.ACTIVE.getCode());
        List<SysUser> userList = sysUserMapper.selectByMap(param);
        if (ObjectUtils.isEmpty(userList)) {
            throw new CommonException("登陆失败，未查询到有效用户");
        }
        SysUser sysUser = userList.get(0);
        String pwd = PwdUtils.aesToMd5(loginReq.getPassword(), "");

        String secret = sysUser.getTotpSecret();
//        Long twoFaCode = loginReq.getTwofa();

//        boolean isRight = TotpUtils.checkCode(secret,twoFaCode);
//        if(!isRight){
//            throw new CommonException("登陆失败，2FA验证码错误");
//        }

        if (!StringUtils.equals(pwd, sysUser.getPasswd())) {
            throw new CommonException("登陆失败，密码错误");
        }

        UserInfoRep result = ModelMapperUtil.getStrictModelMapper().map(sysUser, UserInfoRep.class);
        LoginUserSession loginUserSession = ModelMapperUtil.getStrictModelMapper().map(sysUser, LoginUserSession.class);
        loginUserSession.setSessionId(loginReq.getSessionId());

        String token = sessionUtil.savSession(loginUserSession);
        sessionUtil.savSessionId(sysUser.getId(),token);
        result.setToken(token);
        Integer loginCount = sysUser.getLoginCount() + 1;

        sysUser = new SysUser();
        sysUser.setId(result.getId());
        sysUser.setLoginCount(loginCount);
        sysUser.setLastLoginTime(new Date());
        sysUser.setLastLoginIp(loginReq.getLastLoginIp());
        sysUser.setLastIpRegion(loginReq.getLastIpRegion());

        sysUserMapper.updateByPrimaryKeySelective(sysUser);

        return result;
    }


    @Override
    public CommonPageRep<SysUserPage> pageSysUser(SysUserPageReq userReq) {
        Page<SysUserPage> page = PageHelper.startPage(userReq.getPageNo(), userReq.getPageSize());
        userReq.setStatus(userReq.getUserStatus().getCode());
        SysUserPrams params = ModelMapperUtil.getStrictModelMapper().map(userReq, SysUserPrams.class);
        params.setStatus(userReq.getUserStatus().getCode());
        sysUserMapper.listSysUser(params);
        return CommonPageRep.buildResultRep(page);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveSysUser(SysUserReq sysUserReq) {

        SysUser user = ModelMapperUtil.getStrictModelMapper().map(sysUserReq, SysUser.class);
        if (ObjectUtils.isEmpty(user.getId())) {

            Map<String, Object> param = new HashMap<>();
            param.put("login_name", user.getLoginName());
            List<SysUser> userList = sysUserMapper.selectByMap(param);
            if(!ObjectUtils.isEmpty(userList)){
                throw new CommonException("登录名已存在");
            }

            String totpSecret = TotpUtils.generateSecretKey();
            user.setPasswd(PwdUtils.aesToMd5(user.getPasswd(), ""));
            user.setCreateTime(new Date());
            user.setUserStatus(AdminUserEnums.Status.ACTIVE.getCode().byteValue());
            user.setTotpSecret(totpSecret);
            user.setTotpQr(TotpUtils.getQRBarcodeURL("insider","findcloud",totpSecret,user.getLoginName()));

            sysUserMapper.insert(user);
            sysUserRoleMapper.insertBatch(user.getId(), sysUserReq.getRoleIds());
        } else {
            String loginName = user.getLoginName();
            user.setLoginName(null);
            if (StringUtils.isNotBlank(user.getPasswd())) {
                String totpSecret = TotpUtils.generateSecretKey();
                user.setTotpSecret(totpSecret);
                user.setTotpQr(TotpUtils.getQRBarcodeURL("insider","findcloud",totpSecret,loginName));
                user.setPasswd(PwdUtils.aesToMd5(user.getPasswd(), ""));
            }
            sysUserMapper.updateById(user);
            deleteSysUserRole(user.getId());
            sysUserRoleMapper.insertBatch(user.getId(), sysUserReq.getRoleIds());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteSysUser(List<Integer> userIdList) {
        for (Integer userId : userIdList){
            SysUser user = sysUserMapper.selectById(userId);
            if (!ObjectUtils.isEmpty(user)) {
                user = new SysUser();
                user.setId(userId);
                user.setUserStatus(AdminUserEnums.Status.DELETE.getCode().byteValue());
                sysUserMapper.updateById(user);
                deleteSysUserRole(userId);
            }
        }
    }

    private void deleteSysUserRole(Integer userId) {
        Map<String, Object> delParam = Maps.newHashMap();
        delParam.put("sys_user_id", userId);
        sysUserRoleMapper.deleteByMap(delParam);
    }

    @Override
    public SysUserResp getSysUserDetailById(Integer userId) {
        SysUser user = sysUserMapper.selectById(userId);
        SysUserResp result = ModelMapperUtil.getStrictModelMapper().map(user, SysUserResp.class);
        result.setPasswd("");
        result.setUserRole(roleMapper.listUserRole(result.getId()));
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void resetPwd(UserResetPwdReq resetPwdReq) {
        SysUser user = sysUserMapper.selectById(resetPwdReq.getUserId());
        if (!ObjectUtils.isEmpty(user)) {
            String loginName = user.getLoginName();
            String totpSecret = TotpUtils.generateSecretKey();
            user = new SysUser();
            user.setId(resetPwdReq.getUserId());
            user.setPasswd(PwdUtils.aesToMd5(resetPwdReq.getNewPwd(), ""));
            user.setTotpSecret(totpSecret);
            String totpQr = TotpUtils.getQRBarcodeURL("insider","findcloud",totpSecret,loginName);
            user.setTotpQr(totpQr);
            sysUserMapper.updateByPrimaryKeySelective(user);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void modifyPwd(UserModifyPwdReq modifyPwdReq) {
        modifyPwdReq.setUserId(sessionUtil.getUser().getId());
        SysUser user = sysUserMapper.selectById(modifyPwdReq.getUserId());
        if (!ObjectUtils.isEmpty(user)) {
            if (!StringUtils.equals(PwdUtils.aesToMd5(modifyPwdReq.getOldPwd(), ""), user.getPasswd())) {
                throw new CommonException("旧密码错误");
            }
            String loginName = user.getLoginName();
            String totpSecret = TotpUtils.generateSecretKey();
            user = new SysUser();
            user.setId(modifyPwdReq.getUserId());
            user.setPasswd(PwdUtils.aesToMd5(modifyPwdReq.getNewPwd(), ""));
            user.setTotpSecret(totpSecret);
            user.setTotpQr(TotpUtils.getQRBarcodeURL("insider","findcloud",totpSecret,loginName));
            sysUserMapper.updateByPrimaryKeySelective(user);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateUserInfoBySession(UserModifyInfoReq userModifyInfoReq) {
        SysUser user = sysUserMapper.selectById(userModifyInfoReq.getId());
        if (!ObjectUtils.isEmpty(user)) {
            user = ModelMapperUtil.getStrictModelMapper().map(userModifyInfoReq, SysUser.class);
            sysUserMapper.updateByPrimaryKeySelective(user);
        }
    }
}
